package com.kelai.service.impl;

import com.google.common.collect.Sets;
import com.kelai.common.InfoPage;
import com.kelai.common.PageInfo;
import com.kelai.common.cache.RedisBean;
import com.kelai.common.constants.ShopStatusEnum;
import com.kelai.common.constants.WebAppConstants;
import com.kelai.domain.CustomerEntity;
import com.kelai.domain.ShopDataDayEntity;
import com.kelai.repository.ICustomerRepository;
import com.kelai.service.IShopDayService;
import com.kelai.utils.BreezeeUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.olap4j.*;
import org.olap4j.metadata.Member;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.sql.DriverManager;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 店铺日统计服务
 * Created by Luffy on 2017/04/21.
 */
@Service("shopDayService")
public class DefaultShopDayService implements IShopDayService {
    private final static Logger logger = LoggerFactory.getLogger(DefaultShopDayService.class);
    private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private ICustomerRepository customerRepository;

    @Autowired
    private RedisBean redisBean;

    @Override
    public List<ShopDataDayEntity> listAll(Map condition) {

        PageInfo pageInfo = new PageInfo(condition);
        if (condition.get("_sort") != null) {
            pageInfo.setSort((Sort) condition.get("_sort"));
        } else {
            pageInfo.setSort(new Sort(Sort.Direction.ASC, "rowNum", "id"));
        }

        List<ShopDataDayEntity> l = new ArrayList<>();
        try {
            logger.info("--ShopDayService listAll--");
            Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");
            OlapConnection con = (OlapConnection) DriverManager.getConnection("jdbc:xmla:Server=http://" + WebAppConstants.BI_LINK_IP + "/MDKL/msmdpump.dll;Catalog=" + WebAppConstants.BI_LINK_NAME);
            OlapWrapper wrapper = (OlapWrapper) con;
            OlapConnection olapConnection = wrapper.unwrap(OlapConnection.class);
            OlapStatement stmt = olapConnection.createStatement();

            StringBuffer strPageBuffer = new StringBuffer();
            strPageBuffer.append(" ");
            strPageBuffer.append(" SELECT NON EMPTY { [Measures].[进], [Measures].[出] } ON 0, ");
            strPageBuffer.append("  {   [组织].[组织ID].[组织ID].ALLMEMBERS *  ");
            strPageBuffer.append(" [时间].[年].[年].ALLMEMBERS * ");
            strPageBuffer.append(" [时间].[月].[月].ALLMEMBERS *  ");
            strPageBuffer.append(" [时间].[日].[日].ALLMEMBERS } on 1 ");
            strPageBuffer.append(" FROM ( SELECT ( { [时间].[年月日小时].[日].&[" + condition.get("_startDate") + "T00:00:00]:[时间].[年月日小时].[日].&[" + condition.get("_endDate") + "T00:00:00] }, {");


            if (StringUtils.isNotEmpty(condition.get("_customerId") + "") &&
                    (StringUtils.isEmpty(condition.get("customer_id_obj_ae") + "") || condition.get("customer_id_obj_ae") == null) && (condition.get("_shopIds") == null || CollectionUtils.isEmpty((List<String>) condition.get("_shopIds")))) {
                CustomerEntity parentCustomer = customerRepository.findOne(condition.get("_customerId") + "");
                Set<CustomerEntity> shops = Sets.newConcurrentHashSet();
                parentCustomer.findDeepChildren(shops);
                Object shopType = condition.get("shopType");
                shops.stream().forEach(shop -> {
                    if (Objects.equals(shop.getStatus(), ShopStatusEnum.ENABLE.getValue())) {
                        if (shopType != null && !Objects.equals("", shopType)) {
                            if (Objects.equals(shop.getShopType(), shopType)) {
                                strPageBuffer.append("  [组织].[组织层次].&[" + shop.getId() + "] , ");
                            }
                        } else {
                            strPageBuffer.append("  [组织].[组织层次].&[" + shop.getId() + "] , ");
                        }
                    }
                });
                strPageBuffer.append("  [组织].[组织层次].&[-1] ");
            } else if (condition.get("_shopIds") != null && CollectionUtils.isNotEmpty((List<String>) condition.get("_shopIds"))) {
                ((List<String>) condition.get("_shopIds")).stream().forEach(shopId -> {
                    strPageBuffer.append("  [组织].[组织层次].&[" + shopId + "] , ");
                });
                strPageBuffer.append("  [组织].[组织层次].&[-1] ");
            } else {
                strPageBuffer.append("  [组织].[组织层次].&[" + condition.get("customer_id_obj_ae") + "]  ");
            }
//            strPageBuffer.append("  [组织].[组织层次].&[9236b103947f4f71b261bcf958286b2c] ");

            strPageBuffer.append(" } ) ON COLUMNS ");
            strPageBuffer.append(" FROM [客流]) ");

            CellSet cellSet = stmt.executeOlapQuery(strPageBuffer.toString());

            for (Position rowPos : cellSet.getAxes().get(1)) {
                String s = "";
                for (Member member : rowPos.getMembers()) {
                    s += member.getCaption() + "*";
                }
                for (Position colPos : cellSet.getAxes().get(0)) {
                    Cell cell = cellSet.getCell(colPos, rowPos);
                    s += cell.getFormattedValue() + "*";
                }
                String[] ss = s.split("\\*");
                String id = ss[0] + "-" + ss[1] + ss[2] + ss[3];
                ShopDataDayEntity sdde = new ShopDataDayEntity();
                sdde.setId(id);
                sdde.setCode(id);

                String shopName = redisBean.get(ss[0]);
                String customerName = redisBean.get(ss[0] + "-parent");
                sdde.setShopId(ss[0]);
                sdde.setShopName(shopName);
                sdde.setCustomerName(customerName);
//                CustomerEntity ce = customerRepository.findOne(ss[0]);
//                sdde.setCustomer(ce);
//                sdde.setCustomerId(ce.getParentId());
                String biDateStr = ss[1] + "-" + ss[2] + "-" + ss[3];
                try {
                    if (biDateStr.indexOf(" ") > 0) {
                        logger.info("~~from bi date has blank~~");
                    }

                    Date biDate = BreezeeUtils.str2Date(biDateStr);
                    sdde.setHappenTime(biDate);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.info("~~~~~~~~~~~~shopDayService method convert date error~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                    logger.info(" date : " + biDateStr);
                }
                sdde.setYear(Integer.parseInt(ss[1]));
                if (ss.length < 5) {
                    sdde.setDxin(0);
                    sdde.setDxout(0);
                } else {
                    sdde.setDxin(Integer.parseInt(ss[4]));
                    sdde.setDxout(Integer.parseInt(ss[5]));
                }
                l.add(sdde);
            }
        } catch (Exception e1) {
            logger.info("导致首页为0的问题 ： " + e1.getMessage());
            e1.printStackTrace();
        }

        return l;
    }

    @Override
    public InfoPage<ShopDataDayEntity> pageAll(Map condition) {
        PageInfo pageInfo = new PageInfo(condition);
        if (condition.get("_sort") != null) {
            pageInfo.setSort((Sort) condition.get("_sort"));
        } else {
            pageInfo.setSort(new Sort(Sort.Direction.ASC, "rowNum", "id"));
        }

        List<ShopDataDayEntity> l = new ArrayList<>();
        String cnt = "0";
        try {
            logger.info("--ShopDayService pageAll--");
            Class.forName("org.olap4j.driver.xmla.XmlaOlap4jDriver");
            OlapConnection con = (OlapConnection) DriverManager.getConnection("jdbc:xmla:Server=http://" + WebAppConstants.BI_LINK_IP + "/MDKL/msmdpump.dll;Catalog=" + WebAppConstants.BI_LINK_NAME);
            OlapWrapper wrapper = (OlapWrapper) con;
            OlapConnection olapConnection = wrapper.unwrap(OlapConnection.class);
            OlapStatement stmt = olapConnection.createStatement();

            Integer pageStart = Integer.parseInt(condition.get("pageNumber").toString()) *
                    Integer.parseInt(condition.get("pageSize").toString());
            Object shopType = condition.get("shopType");

            StringBuffer strPageBuffer = new StringBuffer();
            strPageBuffer.append(" ");
            strPageBuffer.append(" SELECT NON EMPTY { [Measures].[进], [Measures].[出] } ON 0, ");
            strPageBuffer.append("  {  subset ");
            strPageBuffer.append(" (( ");
            strPageBuffer.append(" [组织].[组织ID].[组织ID].ALLMEMBERS *  ");
            strPageBuffer.append(" [时间].[年].[年].ALLMEMBERS * ");
            strPageBuffer.append(" [时间].[月].[月].ALLMEMBERS *  ");
            strPageBuffer.append(" [时间].[日].[日].ALLMEMBERS ) ");
            strPageBuffer.append(" ," + pageStart + " ," + condition.get("pageSize") + ")} on 1 ");
            strPageBuffer.append(" FROM ( SELECT ( { [时间].[年月日小时].[日].&[" + condition.get("_startDate") + "T00:00:00]:[时间].[年月日小时].[日].&[" + condition.get("_endDate") + "T00:00:00] }, {");

            if (StringUtils.isNotEmpty(condition.get("_customerId") + "") &&
                    (StringUtils.isEmpty(condition.get("customer_id_obj_ae") + "") || condition.get("customer_id_obj_ae") == null) && (condition.get("_shopIds") == null || CollectionUtils.isEmpty((List<String>) condition.get("_shopIds")))) {
                CustomerEntity parentCustomer = customerRepository.findOne(condition.get("_customerId") + "");
                Set<CustomerEntity> shops = Sets.newConcurrentHashSet();
                parentCustomer.findDeepChildren(shops);
                shops.stream().forEach(shop -> {
                    if (Objects.equals(shop.getStatus(), ShopStatusEnum.ENABLE.getValue())) {
                        if (shopType != null && !Objects.equals("", shopType)) {
                            if (Objects.equals(shop.getShopType(), shopType)) {
                                strPageBuffer.append("  [组织].[组织层次].&[" + shop.getId() + "] , ");
                            }
                        } else {
                            strPageBuffer.append("  [组织].[组织层次].&[" + shop.getId() + "] , ");
                        }
                    }
                });
                strPageBuffer.append("  [组织].[组织层次].&[-1] ");
            } else if (condition.get("_shopIds") != null && CollectionUtils.isNotEmpty((List<String>) condition.get("_shopIds"))) {
                ((List<String>) condition.get("_shopIds")).stream().forEach(shopId -> {
                    strPageBuffer.append("  [组织].[组织层次].&[" + shopId + "] , ");
                });
                strPageBuffer.append("  [组织].[组织层次].&[-1] ");
            } else {
                strPageBuffer.append("  [组织].[组织层次].&[" + condition.get("customer_id_obj_ae") + "]  ");
            }

            strPageBuffer.append(" } ) ON COLUMNS ");
            strPageBuffer.append(" FROM [客流]) ");

            CellSet cellSet = stmt.executeOlapQuery(strPageBuffer.toString());

            for (Position rowPos : cellSet.getAxes().get(1)) {
                String s = "";
                for (Member member : rowPos.getMembers()) {
                    s += member.getCaption() + "*";
                }
                for (Position colPos : cellSet.getAxes().get(0)) {
                    Cell cell = cellSet.getCell(colPos, rowPos);
                    s += cell.getFormattedValue() + "*";
                }
                String[] ss = s.split("\\*");
                String id = ss[0] + "-" + ss[1] + ss[2] + ss[3];
                ShopDataDayEntity sdde = new ShopDataDayEntity();
                sdde.setId(id);
                sdde.setCode(id);

                String shopName = redisBean.get(ss[0]);
                String customerName = redisBean.get(ss[0] + "-parent");
                sdde.setShopId(ss[0]);
                sdde.setShopName(shopName);
                sdde.setCustomerName(customerName);
//                CustomerEntity ce = customerRepository.findOne(ss[0]);
//                sdde.setCustomer(ce);
//                sdde.setCustomerId(ce.getParentId());
                String biDateStr = ss[1] + "-" + ss[2] + "-" + ss[3];
                try {
                    if (biDateStr.indexOf(" ") > 0) {
                        logger.info("~~from bi date has blank~~");
                    }

                    Date biDate = BreezeeUtils.str2Date(biDateStr);
                    sdde.setHappenTime(biDate);
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.info("~~~~~~~~~~~~shopDayService method convert date error~~~~~~~~~~~~~~~~~~~~~~~~~~~");
                    logger.info(" date : " + biDateStr);
                }
                sdde.setYear(Integer.parseInt(ss[1]));
                if (ss.length < 5) {
                    sdde.setDxin(0);
                    sdde.setDxout(0);
                } else {
                    sdde.setDxin(Integer.parseInt(ss[4]));
                    sdde.setDxout(Integer.parseInt(ss[5]));
                }
                l.add(sdde);
            }


//        System.out.println(" 客户       门店       设备名称 设备位置 进店数 出店数 时间");
//        l.forEach( shopDayData -> {
//            System.out.println( shopDayData.getCustomerName() + " "+shopDayData.getShopName() + "     --    --      " + shopDayData.getDxin() + " "+shopDayData.getDxout() + " " +shopDayData.getHappenTime());
//        });

            StringBuffer strCntBuffer = new StringBuffer();
            strCntBuffer.append(" ");
            strCntBuffer.append(" WITH ");
            strCntBuffer.append(" SET [xx] as ({[组织].[组织ID].[组织ID].ALLMEMBERS * [时间].[年].[年].ALLMEMBERS * [时间].[月].[月].ALLMEMBERS *[时间].[日].[日].ALLMEMBERS* [Measures].[进]}) ");
            strCntBuffer.append(" MEMBER [Measures].[X] AS count([xx]) ");
            strCntBuffer.append(" SELECT Measures.X ON 0 ");
            strCntBuffer.append(" FROM ( SELECT ( { [时间].[年月日小时].[日].&[" + condition.get("_startDate") + "T00:00:00]:[时间].[年月日小时].[日].&[" + condition.get("_endDate") + "T00:00:00] },{ ");

            if (StringUtils.isNotEmpty(condition.get("_customerId") + "") &&
                    (StringUtils.isEmpty(condition.get("customer_id_obj_ae") + "") || condition.get("customer_id_obj_ae") == null) && (condition.get("_shopIds") == null || CollectionUtils.isEmpty((List<String>) condition.get("_shopIds")))) {
                CustomerEntity parentCustomer = customerRepository.findOne(condition.get("_customerId") + "");
                Set<CustomerEntity> shops = Sets.newConcurrentHashSet();
                parentCustomer.findDeepChildren(shops);
                shops.stream().forEach(shop -> {
                    if (Objects.equals(shop.getStatus(), ShopStatusEnum.ENABLE.getValue())) {
                        if (shopType != null && !Objects.equals("", shopType)) {
                            if (Objects.equals(shop.getShopType(), shopType)) {
                                strCntBuffer.append("  [组织].[组织层次].&[" + shop.getId() + "] , ");
                            }
                        } else {
                            strCntBuffer.append("  [组织].[组织层次].&[" + shop.getId() + "] , ");
                        }
                    }
                });
                strCntBuffer.append("  [组织].[组织层次].&[-1] ");
            } else if (condition.get("_shopIds") != null && CollectionUtils.isNotEmpty((List<String>) condition.get("_shopIds"))) {
                ((List<String>) condition.get("_shopIds")).stream().forEach(shopId -> {
                    strCntBuffer.append("  [组织].[组织层次].&[" + shopId + "] , ");
                });
                strCntBuffer.append("  [组织].[组织层次].&[-1] ");
            } else {
                strCntBuffer.append("  [组织].[组织层次].&[" + condition.get("customer_id_obj_ae") + "]  ");
            }

            strCntBuffer.append("  } ) ON COLUMNS ");
            strCntBuffer.append(" FROM [客流]) ");

            CellSet cellSetCnt = stmt.executeOlapQuery(strCntBuffer.toString());

            for (Position rowPos : cellSetCnt.getAxes().get(0)) {
                Cell cell = cellSetCnt.getCell(rowPos);
                cnt = cell.getFormattedValue();
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        return new InfoPage<ShopDataDayEntity>(l, new Long(cnt));
    }
}
